<?php

class File implements iFile {
	
	private
		$exists = false,
		$path = false,
		$isDir = false,
		$basename = false,
		$dirName = false,
		$extension = false,
		$size = null,
		$mtime = null,
		$permsNum = 0,
		$permsStr = null;
	
	public function __construct($path) {
		$this->path = $path;
		
		if (file_exists($path)) {
			$this->exists = true;
			
			if (is_dir($path)) {
				$this->isDir = true;
				
				$info = pathinfo($path);
							
				$this->basename = $info['basename'];
				$this->dirName = $info['dirname'];
			} elseif (is_file($path)) {
				$info = pathinfo($path);
				
				$this->basename = $info['basename'];
				$this->dirName = $info['dirname'];
				$this->extension = isset($info['extension']) ? $info['extension'] : '';
			}
		} else {
			$this->size = false;
			$this->permsStr = false;
		}
	}
	
	public function getIsDir() {
		return $this->isDir;
	}
	
	public function getPath() {
		return $this->path;
	}
	
	public function getDirName() {
		return $this->dirName;
	}
	
	public function getBasename() {
		return $this->basename;
	}
	
	public function getExtension() {
		return $this->extension;
	}
	
	public function getSize() {
		if ($this->size !== null) {
			return $this->size;
		}
		
		if ($this->isDir) {
			return $this->size = false;
		}
		
		return $this->size = filesize($this->path);
	}
	
	public function getMTime() {
		if ($this->mtime !== null) {
			return $this->mtime;
		}
		
		if ($this->isDir) {
			return $this->mtime = false;
		}
		
		return $this->mtime = formatDate(filemtime($this->path));
	}
	
	public function getPerms() {
		if ($this->permsStr) {
			return $this->permsStr;
		}
		
		$this->permsNum = $perms = fileperms($this->path);
		
		if (($perms & 0xC000) == 0xC000) {
		    // Socket
		    $info = 's';
		} elseif (($perms & 0xA000) == 0xA000) {
		    // Symbolic Link
		    $info = 'l';
		} elseif (($perms & 0x8000) == 0x8000) {
		    // Regular
		    $info = '-';
		} elseif (($perms & 0x6000) == 0x6000) {
		    // Block special
		    $info = 'b';
		} elseif (($perms & 0x4000) == 0x4000) {
		    // Directory
		    $info = 'd';
		} elseif (($perms & 0x2000) == 0x2000) {
		    // Character special
		    $info = 'c';
		} elseif (($perms & 0x1000) == 0x1000) {
		    // FIFO pipe
		    $info = 'p';
		} else {
		    // Unknown
		    $info = 'u';
		}
		
		// Owner
		$info .= (($perms & 0x0100) ? 'r' : '-');
		$info .= (($perms & 0x0080) ? 'w' : '-');
		$info .= (($perms & 0x0040) ?
		            (($perms & 0x0800) ? 's' : 'x' ) :
		            (($perms & 0x0800) ? 'S' : '-'));
		
		// Group
		$info .= (($perms & 0x0020) ? 'r' : '-');
		$info .= (($perms & 0x0010) ? 'w' : '-');
		$info .= (($perms & 0x0008) ?
		            (($perms & 0x0400) ? 's' : 'x' ) :
		            (($perms & 0x0400) ? 'S' : '-'));
		
		// World
		$info .= (($perms & 0x0004) ? 'r' : '-');
		$info .= (($perms & 0x0002) ? 'w' : '-');
		$info .= (($perms & 0x0001) ?
		            (($perms & 0x0200) ? 't' : 'x' ) :
		            (($perms & 0x0200) ? 'T' : '-'));
		
		return $this->permsStr = $info;
	}
	
	public function delete() {
		if ($this->isDir) {
			return FilesController::getFolder($this->path)->delete();
			
			return rmdir($this->path);
		}
		
		return unlink($this->path);
	}
	
	public function __toXML(DOMDocument $xml) {
		$fileNode = $xml->createElement('file');
		$fileNode->setAttribute('name', iconv('CP1251', 'UTF-8//TRANSLIT', $this->getBasename()));
		$fileNode->setAttribute('dir', $this->isDir ? 1 : 0);
		
		$dirname = trim(substr($this->getDirName(), mb_strlen(DOC_ROOT)), '/');
		
		$fileNode->appendChild($xml->createElement('dirname', iconv('CP1251', 'UTF-8//TRANSLIT', $dirname)));
		$fileNode->appendChild($xml->createElement('extension', (string) $this->getExtension()));
		$fileNode->appendChild($xml->createElement('size', (string) $this->getSize()));
		$fileNode->appendChild($xml->createElement('mtime', $this->getMTime()));
		
		$permsNode = $xml->createElement('perms', $this->getPerms());
		$permsNode->setAttribute('num', substr(decoct($this->permsNum), 2));
		
		$fileNode->appendChild($permsNode);
		
		return $fileNode;
	}
	
}